﻿using Stardust.Common.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace Stardust.Server
{

    class StardustHttpHandler : IHttpAsyncHandler
    {
        public static StardustHttpHandler Instance = new StardustHttpHandler();
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            StardustAsyncResult result = new StardustAsyncResult(context, cb);
            result.StartAsyncWork();
            return result;
        }

        public void EndProcessRequest(IAsyncResult result)
        {
            var stardustResult = result as StardustAsyncResult;
            SerializerHelper.SerializeToStream(stardustResult.Result, stardustResult.Result.GetType(), stardustResult.Context.Response.OutputStream);
            if (stardustResult.StatusCode != 200)
            {
                stardustResult.Context.Response.StatusCode = stardustResult.StatusCode;
            }
            stardustResult.Context.Response.End();
        }

        public void ProcessRequest(HttpContext context)
        {
            //异步Handler不执行这个方法
        }
    }

    class StardustAsyncResult : IAsyncResult
    {

        AsyncCallback _callback;

        public StardustAsyncResult(HttpContext context, AsyncCallback cb)
        {
            Context = context;
            _callback = cb;
            StatusCode = 200;
        }

        public object Result
        {
            get;
            private set;
        }
        public int StatusCode { get; private set; }
        public void StartAsyncWork()
        {
            //进入stardust
            var path = Context.Request.RawUrl.Remove(0, StardustServer.StardustRoot.Length);
            var json = string.Empty;
            if (Context.Request.ContentLength > 0)
            {
                StreamReader sr = new StreamReader(Context.Request.InputStream);
                json = sr.ReadToEnd();
            }
            if (string.IsNullOrEmpty(path) || path == "/")
            {
                Result = "Hello Stardust!";
                SetComplete();
            }
            else
            {
                var actionWrapper = ActionManager.GetActionWrapper(path);
                if (actionWrapper != null)
                {
                    var obj = actionWrapper.Invoke(json);
                    if (actionWrapper.IsAsync)
                    {
                        var task = obj as Task<object>;
                        task.ContinueWith((t) =>
                        {
                            Result = t.Result;
                            SetComplete();
                        });
                    }
                    else
                    {
                        Result = obj;
                        SetComplete();
                    }
                }
                else
                {
                    Result = "没有找到服务:" + path;
                    StatusCode = 404;
                    SetComplete();
                }
            }
        }

        void SetComplete()
        {
            IsCompleted = true;
            if (_callback != null)
            {
                _callback(this);
            }
        }

        public HttpContext Context
        {
            get;
            private set;
        }

        public bool IsCompleted
        {
            get;
            private set;
        }

        public object AsyncState
        {
            get
            {
                return null;
            }
        }

        public WaitHandle AsyncWaitHandle
        {
            get
            {
                return null;
            }
        }

        public bool CompletedSynchronously
        {
            get
            {
                return false;
            }
        }
    }
}
